# -*- coding: utf-8 -*-
from typing import Optional

from zinx.ziface.imessage import IMessage
from zinx.znet.message import NewMessage
from zinx.ziface.idatapack import IDataPack
from zinx.utils.globalobj import GlobalObject


class DataPack(IDataPack):
    """
    采用经典的TLV(Type-Len-Value)封包格式
    每一个数据包的格式如下：
        DataLen | ID    | Data
        数据长度 | 数据ID | 数据内容
    每一个数据包的格式统一，从TCP流中读取数据，就按照这个格式进行解析。
    """
    def __init__(self):
        pass

    def GetHeadLen(self) -> int:
        """
        获取包头长度方法
        :return:
        """
        # Id uint32(4字节) +  DataLen uint32(4字节)
        return 8

    def Pack(self, msg: IMessage) -> bytes:
        """
        封包方法
        :param msg:
        :return:
        """
        # 创建一个存放bytes字节的缓冲
        buffer = bytes()
        # 写dataLen
        buffer += msg.GetDataLen().to_bytes(4, "little")
        # 写msgID
        buffer += msg.GetMsgId().to_bytes(4, "little")
        # 写data数据
        buffer += msg.GetData()
        return buffer

    def Unpack(self, data: bytes) -> Optional[IMessage]:
        """
        拆包方法
        :param data:
        :return:
        """
        # 读dataLen
        data_len = int.from_bytes(data[:4], byteorder='little', signed=False)
        # 度msgID
        msg_id = int.from_bytes(data[4:], byteorder='little', signed=False)
        # 判断dataLen的长度是否超出我们允许的最大包长度
        if 0 < GlobalObject.MaxPacketSize < data_len:
            return None
        msg = NewMessage(msg_id, data_len, bytes())
        # 这里只需要把head的数据拆包出来就可以了，然后再通过head的长度，再从conn读取一次数据
        return msg


def NewDataPack() -> IDataPack:
    dp = DataPack()
    return dp
